package com.bsj.power.pls.handle;

import com.alibaba.fastjson.JSONObject;
import com.bsj.power.common.config.rocketmq.producer.BaseMqPushUtil;
import com.bsj.power.common.def.dto.locationDevice.TagAlarmDetailDTO;
import com.bsj.power.common.def.dto.locationDevice.TagAlarmMsgDTO;
import com.bsj.power.common.def.dto.locationDevice.TagMsgDTO;
import com.bsj.power.common.util.ExceptionUtil;
import com.bsj.power.pls.queue.MsgQueue;
import com.bsj.power.pls.queue.TagAlarmMsgQueue;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author LiJiaXin
 * @version 1.0.0
 * @description WebSocketClientHandle
 * @time 2024/5/21 15:22
 */
@Slf4j
@Component
public class WebSocketClientHandle {

    @Autowired
    private MsgQueue msgQueue;

    @Autowired
    private TagAlarmMsgQueue tagAlarmMsgQueue;

    @Autowired
    private BaseMqPushUtil baseMqPushUtil;

    @Value("${teteTool.cmd}")
    public String cmd;

    public WebSocketClientUntil posWebSocketClientUntil;
    public WebSocketClientUntil alarmWebSocketClientUntil;
    private ScheduledExecutorService executorService;
    //    private ScheduledExecutorService alarmExecutorService;
    private static final String posTopic = "{ \n" +
            "    \"type\": 3,\n" +
            "    \"data\": \"{\\\"messageType\\\":14,\\\"end\\\":false}\" \n" +
            "}";

    private static final String alarmTopic = "{\n" +
            "\t\"type\": 3,\n" +
            "\t\"data\": \"{\\\"messageType\\\":1,\\\"messageGroupIds\\\":[\\\"1\\\"],\\\"end\\\":false}\"\n" +
            "}";

    public void start(String wsUrl) throws Exception {
        //第一个为位置数据推送，第二个为电子围栏报警推送
        String[] split = wsUrl.split(";");
        executorService = Executors.newSingleThreadScheduledExecutor();
//        alarmExecutorService = Executors.newSingleThreadScheduledExecutor();
        //位置数据推送
        if (posWebSocketClientUntil == null) {
            posWebSocketClientUntil = new WebSocketClientUntil(new URI(split[0]));
            posWebSocketClientUntil.connect();
            Thread.sleep(2000);
            boolean open = posWebSocketClientUntil.getConnection().isOpen();
            log.info("websocket订阅位置消息客户端开启状态: {}", open);
            //TODO 正常接收定位系统数据
            if (open) {
                posWebSocketClientUntil.send(JSONObject.parseObject(posTopic).toJSONString());
                //TODO 模拟工具五个设备发送位置数据
//            posWebSocketClientUntil.send(cmd);
                log.info("启动成功，订阅位置消息发出");
            } else {
                posWebSocketClientUntil.posStartReconnectTask();
            }
        }
        //电子围栏报警推送
        if (alarmWebSocketClientUntil == null) {
            alarmWebSocketClientUntil = new WebSocketClientUntil(new URI(split[1]));
            alarmWebSocketClientUntil.connect();
            Thread.sleep(2000);
            boolean open = alarmWebSocketClientUntil.getConnection().isOpen();
            log.info("websocket订阅报警消息客户端开启状态: {}", open);
            if (open) {
                posWebSocketClientUntil.send(JSONObject.parseObject(alarmTopic).toJSONString());
                log.info("启动成功，订阅报警消息发出");
            } else {
                alarmWebSocketClientUntil.alarmStartReconnectTask();
            }
        }
    }

    public void stop() {
//        ws://192.168.130.167:18080/notify?sessionId=c656eae1-cddd-44c8-8b33-3f4d0a816d21
        if (posWebSocketClientUntil != null) {
            posWebSocketClientUntil.close();
        }
        if (alarmWebSocketClientUntil != null) {
            alarmWebSocketClientUntil.close();
        }
    }

    public class WebSocketClientUntil extends WebSocketClient {

        @Value("${myUrl.wsUrl}")
        private String wsUrl;

        @Autowired
        private WebSocketClientHandle webSocketClientHandle;

        public void posStartReconnectTask() {
            executorService.scheduleWithFixedDelay(() -> {
                if (!this.isOpen()) {
                    log.warn("websocket客户端位置信息订阅重新连接...");
                    this.reconnect();
                    try {
                        Thread.sleep(2000);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    this.send(JSONObject.parseObject(posTopic).toJSONString());
                }
            }, 0, 5, TimeUnit.SECONDS);
        }

        public void alarmStartReconnectTask() {
            executorService.scheduleWithFixedDelay(() -> {
                if (!this.isOpen()) {
                    log.warn("websocket客户端报警信息订阅重新连接...");
                    this.reconnect();
                    try {
                        Thread.sleep(2000);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    this.send(JSONObject.parseObject(alarmTopic).toJSONString());
                }
            }, 0, 5, TimeUnit.SECONDS);
        }

        public WebSocketClientUntil(URI serverUri) {
            super(serverUri);
        }

        @Override
        public void onOpen(ServerHandshake serverHandshake) {
            System.err.println("连接打开");
        }

        @Override
        public void onMessage(String str) {
            log.info("WebSocketClientUntil接收消息内容: {}", str);
            if (StringUtils.isNotEmpty(str)) {
                JSONObject object = JSONObject.parseObject(str);
                //14表示标签相关消息
                Integer type = object.getInteger("type");
                String data = object.getString("data");

                //标签数据
                if (type == 14) {
                    TagMsgDTO tagMsgDTO = JSONObject.parseObject(data, TagMsgDTO.class);
                    if (tagMsgDTO != null) {
                        try {
                            //因为数据接收太快，只进行每秒一条数据存储
                            tagMsgDTO.setNow(System.currentTimeMillis() / 1000);
                            msgQueue.push(tagMsgDTO);
                        } catch (Exception e) {
                            log.error("msgQueue写入数据失败:" + ExceptionUtil.getStackStr(e));
                        }
                    }
                } else if (type == 7) {
                    TagAlarmMsgDTO tagAlarmMsgDTO = JSONObject.parseObject(data, TagAlarmMsgDTO.class);
                    //电子围栏告警消息
                    if (tagAlarmMsgDTO != null && tagAlarmMsgDTO.getType() == 10) {
                        try {
                            log.info("接收到电子围栏报警信息：{}", tagAlarmMsgDTO);
                            tagAlarmMsgQueue.push(tagAlarmMsgDTO);
                        } catch (Exception e) {
                            log.error("tagAlarmMsgQueue写入数据失败:" + ExceptionUtil.getStackStr(e));
                        }
                    }
                }

            }
        }

        @Override
        public void onClose(int i, String s, boolean b) {
            if (this == posWebSocketClientUntil) {
                posStartReconnectTask();
            }
            if (this == alarmWebSocketClientUntil) {
                alarmStartReconnectTask();
            }
//            boolean open;
//            open = posWebSocketClientUntil.getConnection().isOpen();
//            if(!open){
//                log.info("posWebSocketClientUntil客户端关闭: {}", s);
//                posStartReconnectTask();
//            }
//            open = alarmWebSocketClientUntil.getConnection().isOpen();
//            if(!open){
//                log.info("alarmWebSocketClientUntil客户端关闭: {}", s);
//                alarmStartReconnectTask();
//            }
        }

        @Override
        public void onError(Exception e) {

        }

    }

    public static void main(String[] args) {
        String str = "{\n" +
                "    \"type\": 7,\n" +
                "    \"data\": \"{\\\"status\\\":1,\\\"type\\\":10,\\\"timeMs\\\":1732588984426,\\\"detail\\\":{\\\"entityId\\\":\\\"5\\\",\\\"entityCategory\\\":\\\"employee\\\",\\\"entityName\\\":\\\"628\\\",\\\"pos\\\":[19.969823819288088,19.63704537935514,1.2059458034010606],\\\"tagId\\\":34,\\\"tagSn\\\":\\\"7719973751219487051\\\",\\\"mapId\\\":34,\\\"mapName\\\":\\\"218-207平面地图\\\",\\\"fenceId\\\":5,\\\"fenceName\\\":\\\"滞留测试\\\"}}\"\n" +
                "}";
        JSONObject jsonObject = JSONObject.parseObject(str);
        Integer type = jsonObject.getInteger("type");
        String data = jsonObject.getString("data");
        if (type == 7) {
            TagAlarmMsgDTO tagAlarmMsgDTO = JSONObject.parseObject(data, TagAlarmMsgDTO.class);
            log.info("报警信息：{}", tagAlarmMsgDTO);
            String detail = tagAlarmMsgDTO.getDetail();
            if (StringUtils.isNotBlank(detail)) {
                TagAlarmDetailDTO tagAlarmDetailDTO = JSONObject.parseObject(detail, TagAlarmDetailDTO.class);
                log.info("报警详情：{}", tagAlarmDetailDTO);
            }
        }
    }

}
